﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Caching;

namespace Fly.Cacheing
{
    /// <summary>
    /// 内存缓存数据管理器
    /// </summary>
    public class MemoryCacheManager
    {
        #region 私有属性
        private readonly MemoryCache _cache;
        private static readonly object Lock = new object();
        private static readonly ConcurrentDictionary<string, MemoryCacheManager> Concurrent; 
        private const string DefultKey = "0E067DFD-AF3D-4675-88B9-719EAA749909";
        #endregion

        #region 构造函数
        /// <summary>
        /// 静态构造函数
        /// </summary>
        static MemoryCacheManager()
        {
            Concurrent = new ConcurrentDictionary<string, MemoryCacheManager>();
        }
        /// <summary>
        /// 实例化 ObjectCacheManager 类
        /// </summary>
        /// <param name="name"></param>
        private MemoryCacheManager(string name)
        {
            _cache = string.IsNullOrWhiteSpace(name) ? new MemoryCache(Guid.NewGuid().ToString()) : new MemoryCache(name);
            Debug.WriteLine("当前缓存对象名：{0}，内存更新时间为：{1}，内存可用率：{2}，可用内存量(单位：字节):{3}", _cache.Name, _cache.PollingInterval, _cache.PhysicalMemoryLimit, _cache.CacheMemoryLimit);
        }

        #endregion

        #region 获取实例

        /// <summary>
        /// 获取 MemoryCacheManager 唯一实例
        /// </summary>
        /// <returns></returns>
        public static MemoryCacheManager GetInstance()
        {
            return GetInstance(DefultKey);
        }

        /// <summary>
        /// 获取 MemoryCacheManager 唯一实例
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static MemoryCacheManager GetInstance(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                name = DefultKey;
            }
            return Concurrent.GetOrAdd(name, fun => new MemoryCacheManager(name));
        }

        #endregion

        #region 属性
        /// <summary>
        /// 获取当前内存管理器的数量
        /// </summary>
        public static int Counts
        {
            get { return Concurrent.Count; }
        }
        /// <summary>
        /// 获取当前内存缓存管理器的缓存对象
        /// </summary>
        public MemoryCache MemoryCache
        {
            get { return _cache; }
        }
        /// <summary>
        /// 获取缓存可使用的物理内存百分比
        /// </summary>
        public long PhysicalMemoryLimit
        {
            get { return _cache.PhysicalMemoryLimit; }
        }
        /// <summary>
        /// 获取计算机上缓存可使用内存的内存量(单位字节)
        /// </summary>
        public long CacheMemoryLimit
        {
            get { return _cache.CacheMemoryLimit; }
        }
        /// <summary>
        /// 获取在缓存更新其统计信息之前需等待的最大时间量
        /// </summary>
        public TimeSpan PollingInterval
        {
            get { return _cache.PollingInterval; }
        }
        /// <summary>
        /// 获取缓存提供的功能说明
        /// </summary>
        public DefaultCacheCapabilities DefaultCacheCapabilities
        {
            get { return _cache.DefaultCacheCapabilities; }
        }

        #endregion

        #region 查询
        /// <summary>
        /// 获取当前缓存管理器的元素数量
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return _cache.Count();
        }
        /// <summary>
        /// 获取满足条件的缓存管理器中的元素数量
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public int Count(Func<KeyValuePair<string, object>, bool> func)
        {
            return _cache.Count(func);
        }
        /// <summary>
        /// 返回类型 <see cref="System.Collections.Generic.IEnumerable&gt;T&lt;"/>
        /// </summary>
        /// <returns></returns>
        public IEnumerable<KeyValuePair<string, object>> AsEnumerable()
        {
            return _cache.AsEnumerable();
        }
        /// <summary>
        /// 确定缓存中是否存在某个缓存值
        /// </summary>
        /// <param name="key">键名</param>
        /// <returns></returns>
        public bool Contains(string key)
        {
            if (string.IsNullOrWhiteSpace(key)) return false;
            return _cache.Contains(key);
        }
        /// <summary>
        /// 通过使用默认的相等比较器确定序列中是否存在指定的元素
        /// </summary>
        /// <param name="value">键/值对</param>
        /// <returns></returns>
        public bool Contains(KeyValuePair<string,object> value)
        {
            if (string.IsNullOrWhiteSpace(value.Key)) return false;
            return _cache.Contains(value);
        }
        /// <summary>
        /// 确定是否存在指定的缓存管理器
        /// </summary>
        /// <param name="name">缓存管理器的名称</param>
        /// <returns></returns>
        public static bool IsExists(string name)
        {
            if (string.IsNullOrWhiteSpace(name)) return false;
            return Concurrent.ContainsKey(name);
        }
        
        #endregion

        public T GetOrAdd<T>(string key, Func<string, object> value)
        {
            if (_cache.Contains(key))
            {
                return (T) _cache.Get(key);
            }
        }
    }
}
